﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data;
using System.IO.Compression;
using System.Data.SqlClient;

namespace DataChannel.Web
{
    public class DataTableHelper
    {

        /// 序列化
        /// </summary>
        /// <param name="dsOriginal"></param>
        /// <returns></returns>
        static byte[] GetBinaryFormatData(DataTable dsOriginal)
        {

            try
            {
                byte[] binaryDataResult = null;
                using (MemoryStream memStream = new MemoryStream())
                {
                    IFormatter brFormatter = new BinaryFormatter();
                    dsOriginal.RemotingFormat = SerializationFormat.Binary;

                    brFormatter.Serialize(memStream, dsOriginal);
                    binaryDataResult = memStream.ToArray();
                    memStream.Close();
                    memStream.Dispose();
                }
                return binaryDataResult;
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="binaryData"></param>
        /// <returns></returns>
        static DataTable RetrieveDataTable(byte[] binaryData)
        {
            DataTable dataSetResult = null;
            try
            {
                using (MemoryStream memStream = new MemoryStream(binaryData))
                {
                    IFormatter brFormatter = new BinaryFormatter();

                    object obj = brFormatter.Deserialize(memStream);
                    dataSetResult = (DataTable)obj;
                    memStream.Close();
                    memStream.Dispose();
                }
                return dataSetResult;
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }
        }

        #region 可序列化对象到byte数组的相互转换
        /// <summary>
        /// 将可序列化对象转成Byte数组
        /// </summary>
        /// <param name="o">对象</param>
        /// <returns>返回相关数组</returns>
        public static byte[] ObjectToByteArray(object o)
        {
            try
            {
                byte[] buffer = null;
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(ms, o);
                    buffer = ms.ToArray();
                    ms.Close();
                    ms.Dispose();
                }

                return buffer;
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }
        }
        /// <summary>
        /// 将可序列化对象转成的byte数组还原为对象
        /// </summary>
        /// <param name="b">byte数组</param>
        /// <returns>相关对象</returns>
        protected static object ByteArrayToObject(byte[] b)
        {
            try
            {
                object o = null;
                using (MemoryStream ms = new MemoryStream(b, 0, b.Length))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    o = bf.Deserialize(ms);
                    ms.Close();
                    ms.Dispose();
                }
                return o;
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {

                GC.Collect();
            }
        }
        #endregion

        #region Gzip压缩类进行流压缩

        public static byte[] OCompress(object oSource)
        {
            try
            {
                byte[] byteSource = ObjectToByteArray(oSource);

                return Compress(byteSource);
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }
        }

        public static object ODecompress(byte[] byteSource)
        {
            try
            {
                byte[] temp = Decompress(byteSource);

                return ByteArrayToObject(temp);
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }
        }
        /// <summary>
        /// 压缩数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Compress(byte[] data)
        {
            try
            {
                byte[] bData;
                using (MemoryStream ms = new MemoryStream())
                {
                    GZipStream stream = new GZipStream(ms, CompressionMode.Compress, true);

                    stream.Write(data, 0, data.Length);
                    stream.Close();
                    stream.Dispose();
                    bData = ms.ToArray();
                    ms.Close();
                    ms.Dispose();
                }
                return bData;
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }
        }

        /// <summary>
        /// 解压数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Decompress(byte[] data)
        {
            try
            {
                byte[] bData;
                using (MemoryStream ms = new MemoryStream())
                {
                    ms.Write(data, 0, data.Length);
                    ms.Position = 0;
                    using (GZipStream stream = new GZipStream(ms, CompressionMode.Decompress, true))
                    {
                        byte[] buffer = new byte[4096];
                        using (MemoryStream temp = new MemoryStream())
                        {
                            int read = stream.Read(buffer, 0, buffer.Length);
                            while (read > 0)
                            {
                                temp.Write(buffer, 0, read);
                                read = stream.Read(buffer, 0, buffer.Length);
                            }
                            //必须把stream流关闭才能返回ms流数据,不然数据会不完整
                            stream.Close();
                            stream.Dispose();
                            ms.Close();
                            ms.Dispose();
                            bData = temp.ToArray();
                            temp.Close();
                            temp.Dispose();
                        }
                    }
                }
                return bData;
            }
            catch (Exception e)
            {

                throw e;
            }
            finally
            {
                GC.Collect();
            }

        }
        #endregion


        static int ReadAllBytesFromStream(Stream stream, byte[] buffer)
        {
            // Use this method is used to read all bytes from a stream.
            int offset = 0;
            int totalCount = 0;
            while (true)
            {
                int bytesRead = stream.Read(buffer, offset, 100);
                if (bytesRead == 0)
                {
                    break;
                }
                offset += bytesRead;
                totalCount += bytesRead;
            }
            return totalCount;
        }




        static string sqlCnctString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["sqlString"].ConnectionString;


        /// <summary>
        /// 将源数据导入指定的临时表
        /// </summary>
        /// <param name="SourceData"></param>
        /// <param name="SourceDataTable"></param>
        public static  void ImportSourceDataToTable( DataTable SourceData, string SourceDataTable)
        {
            SqlConnection sqlConnection = new SqlConnection(sqlCnctString);
            try
            {
                if (sqlConnection.State != ConnectionState.Open)
                {
                    sqlConnection.Open();
                }

            }
            catch (Exception)
            {
            }
            using (SqlTransaction transaction =
                      sqlConnection.BeginTransaction())
            {
               
                try
                {

                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
                               sqlConnection, SqlBulkCopyOptions.KeepIdentity,
                               transaction))
                    {
                        bulkCopy.BatchSize = 1000;
                        bulkCopy.BulkCopyTimeout = 0;
                        bulkCopy.DestinationTableName = SourceDataTable;

                        // Write from the source to the destination.

                        bulkCopy.WriteToServer(SourceData);

                        transaction.Commit();
                    }
                }
                catch (Exception ex)
                {

                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception)
                    {

                    }
                    throw ex;
                }
                finally
                {

                    if (sqlConnection != null &&
                        sqlConnection.State == ConnectionState.Open)
                    {
                        try
                        {
                            sqlConnection.Close();
                        }
                        catch (Exception)
                        {
                        }
                    }
                }

            }
        }

    }
}
